﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml.Serialization;
using System.IO;
using Newtonsoft.Json.Linq;
using Core;

namespace Web
{
    public class ReqWrapperBase
    {
        protected T LoadFromXml<T>(string xml, dynamic data = null) {
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(SqlSetting));
            byte[] bytes = System.Text.Encoding.UTF8.GetBytes(xml);
            MemoryStream ms = new MemoryStream(bytes, 0, bytes.Length);
            var sqllSetting = xmlSerializer.Deserialize(ms);
            return (T)sqllSetting;
        }

        protected virtual OperateType OperateType { get; set; }

        protected JObject _data;
        public ReqWrapperBase(JObject data, OperateType operateType) {
            _data = data;
            this.OperateType = operateType;
        }


        public ParamBase ToParam(string xml) {
            xml = GetXml(xml);
            var setting = LoadFromXml<SqlSetting>(xml);
            var param = new ParamBase();
            param.Table = setting.Table;
            param.Operator = this.OperateType;
            PopulateParam(param, setting);
            return param;
        }

        public ParamBase ToParam(SqlSetting setting) {
            var param = new ParamBase();
            param.Table = setting.Table;
            param.Operator = this.OperateType;
            PopulateParam(param, setting);
            return param;
        }

        protected virtual string GetXml(string xml) {
            if (xml.EndsWith(".xml", StringComparison.InvariantCultureIgnoreCase)) {
                var path = HttpContext.Current.Server.MapPath("~\\SqlSettings\\" + xml);
                using (StreamReader sr = new StreamReader(path)) {
                    return sr.ReadToEnd();
                }
            } else {
                return xml;
            }
        }

        protected void PopulateParam(ParamBase param, SqlSetting setting) {
            param.FieldAlls = (from x in _data.Properties()
                               select new Core.Field() { Name = x.Name, Value = x.Value + "" }).ToList();
            if (setting.FieldInserts != null && setting.FieldInserts.Count > 0) {
                if (setting.FieldInserts.Any(x => !x.IsIgnore)) {
                    param.FieldInserts = param.FieldAlls.Where(x => setting.FieldInserts.Any(o => o.Name == x.Name && !o.IsIgnore)).ToList();
                } else {
                    param.FieldInserts = param.FieldAlls.Where(x => !setting.FieldInserts.Any(o => o.Name == x.Name && o.IsIgnore)).ToList();
                }
            } else {
                param.FieldInserts = param.FieldAlls;
            }
            /*if (!param.FieldInserts.Any(x => x.Name.Equals("creation_userid", StringComparison.InvariantCultureIgnoreCase))) {
                param.FieldInserts.Add(new Core.Field("creation_userid", Commons.User.user_id + ""));
                param.FieldInserts.Add(new Core.Field("creation_date", Commons.ServerDateTime.ToString("yyyy-MM-dd HH:mm:ss")));
            } else {
                param.FieldInserts.FirstOrDefault(
                    x => x.Name.Equals("creation_useid", StringComparison.InvariantCultureIgnoreCase)).Value =
                    Commons.User.user_id + "";
                param.FieldInserts.FirstOrDefault(
                    x => x.Name.Equals("creation_date", StringComparison.InvariantCultureIgnoreCase)).Value =
                    Commons.ServerDateTime.ToString("yyyy-MM-dd HH:mm:ss");
            }*/

            if (setting.FieldUpdates != null && setting.FieldUpdates.Count > 0) {
                if (setting.FieldUpdates.Any(x => !x.IsIgnore)) {
                    param.FieldUpdates = param.FieldAlls.Where(x => setting.FieldUpdates.Any(o => o.Name == x.Name && !o.IsIgnore)).ToList();
                } else {
                    param.FieldUpdates = param.FieldAlls.Where(x => !setting.FieldUpdates.Any(o => o.Name == x.Name && o.IsIgnore) || setting.Where.Fields.Any(m => m.Name == x.Name)).ToList();
                }
            } else {
                param.FieldUpdates = (from x in param.FieldAlls.Where(o => !setting.Where.Fields.Any(m => m.Name == o.Name))
                                      select x).ToList();
            }
            /*if (!param.FieldInserts.Any(x => x.Name.Equals("update_userid", StringComparison.InvariantCultureIgnoreCase))) {
                param.FieldInserts.Add(new Core.Field("update_userid", Commons.User.user_id + ""));
                param.FieldInserts.Add(new Core.Field("update_date", Commons.ServerDateTime.ToString("yyyy-MM-dd HH:mm:ss")));
            } else {
                param.FieldInserts.FirstOrDefault(
                    x => x.Name.Equals("update_useid", StringComparison.InvariantCultureIgnoreCase)).Value =
                    Commons.User.user_id + "";
                param.FieldInserts.FirstOrDefault(
                    x => x.Name.Equals("update_date", StringComparison.InvariantCultureIgnoreCase)).Value =
                    Commons.ServerDateTime.ToString("yyyy-MM-dd HH:mm:ss");
            }*/

            if (this.OperateType == OperateType.Update) {
                param.FieldWheres = (from x in param.FieldAlls.Where(o => setting.WhereUpdate.Fields.Any(m => m.Name == o.Name))
                                     select x).ToList();

            } else if (this.OperateType == OperateType.Delete) {
                param.FieldWheres = (from x in param.FieldAlls.Where(o => setting.WhereDelete.Fields.Any(m => m.Name == o.Name))
                                     select x).ToList();
            } else {
                param.FieldWheres = (from x in param.FieldAlls.Where(o => setting.Where.Fields.Any(m => m.Name == o.Name))
                                     select x).ToList();
            }
        }

    }
}